Public Class firmware
    Private m_data(0 To 131071) As Byte
    Private m_lngHandle As Integer = 0

    Sub New()
        dataClean()
    End Sub
    Sub New(ByVal lngHandle As Integer)
        dataClean()
        m_lngHandle = lngHandle
    End Sub
    Sub New(ByVal lngHandle As Integer, ByRef data() As Byte)
        m_lngHandle = lngHandle
        dataLoad(data)
    End Sub

    Public Sub dataLoad(ByRef Data_() As Byte)
        dataClean()
        For i As Integer = 0 To UBound(Data_)
            m_data(i) = Data_(i)
        Next
    End Sub
    Private Sub dataClean()
        For i As Integer = 0 To 131071
            m_data(i) = 255
        Next
    End Sub

    ' Returns True is page contains data other than FF's
    Private Function pageCheck(ByVal PageNo As Integer) As Boolean
        Dim check As Boolean = False
        Dim i As Integer
        For i = PageNo * 256 To PageNo * 256 + 256
            If m_data(i) <> &HFFS Then
                check = True
            End If
        Next
        Return check
    End Function

    Public Function UploadTwo() As Boolean
        Dim f_count As Integer
        Dim f_retBytes(0 To 20) As Byte
        Dim f_pageData(0 To 280) As Byte
        Dim f_page(0 To 1) As Byte
        Dim s_crc As Integer
        Dim f_error As Integer
        Dim f_returnBytes(0 To 20) As Byte
        Dim f_bytes() As Byte = usb_read(f_count)
        Dim retValue As Boolean = True
        'Console.WriteLine("USB connected" & f_bytes(0) & f_bytes(1))


        If f_bytes(0) = 187 And f_bytes(1) = 175 Then
            For i As Integer = 0 To 495
                If pageCheck(i) Then
                    f_page(0) = HIBYTE(i)
                    f_page(1) = LOBYTE(i)
                    If BikiRom_sendCmdd(f_page, f_returnBytes, 2, 1) Then
                        If f_returnBytes(0) = 170 Then
resendPage:
                            array_copy(m_data, i * 256, f_pageData, 0, 256)
                            s_crc = 0
                            For s_i As Integer = 0 To 255
                                s_crc += f_pageData(s_i)
                            Next
                            f_pageData(256) = LOBYTE(s_crc)
                            Console.WriteLine(f_pageData(256))
                            Console.WriteLine("DATA: " & s_crc & "CRC calc of : " & f_pageData(256))
                            If BikiRom_sendCmdd(f_pageData, f_returnBytes, 257, 2) Then
                                If f_returnBytes(0) = 223 And f_returnBytes(1) = 175 Then
                                    Err_message("Page " & Hex(i) & " Written OK!")
                                ElseIf f_returnBytes(0) = 238 And f_returnBytes(1) = 175 Then
                                    f_error += 1
                                    If f_error <= 100 Then GoTo resendPage
                                Else
                                    Err_message("Error on return bytes: " & f_returnBytes(0) & " " & f_returnBytes(1))
                                    retValue = False
                                    Exit For
                                End If
                            Else
                                Console.WriteLine("Error Sending Page Data")
                                retValue = False
                                Exit For
                            End If
                        End If
                    End If
                End If
            Next
            f_page(0) = 1
            f_page(1) = 255
            BikiRom_sendCmdd(f_page, f_retBytes, 2, 0)
        End If
        bootReset()
        Return retValue
    End Function
    
    Private Function usb_read(ByRef RxBytes As Integer) As Byte()
        Dim retBytes(512) As Byte
        FT_GetQueueStatus(m_lngHandle, RxBytes)
        If RxBytes > 0 Then
            FT_Read_Bytes(m_lngHandle, retBytes(0), RxBytes, RxBytes)
        End If
        Return retBytes
    End Function

    Public Function Upload(ByVal EnableCheckByte As Boolean) As Boolean
        Dim f_return As Boolean = False
        Dim f_read(0 To 6) As Byte
        Dim f_count As Integer
        Dim s_crc As Long
        Dim f_pageData(285) As Byte
        Dim f_page() As Byte = {0, 0}
        Dim f_error As Integer = 0
        Dim f_pageLength As Integer = 257
        If Not EnableCheckByte Then
            f_pageLength = 256
        End If
        FT_Purge(m_lngHandle, FT_PURGE_RX + FT_PURGE_TX)
        bootLoad()

        Threading.Thread.Sleep(200)

        Dim f_returnB() As Byte = usb_read(f_count)
        Console.WriteLine(f_returnB(0) & " " & f_returnB(1))
        Return False
        Exit Function

        If FT_Read_Bytes(lngHandle, f_read(0), 2, f_count) = FT_OK Then
            Console.WriteLine("Inside the bootloader!")
            If f_read(0) = 187 And f_read(1) = 175 Then
                For i As Integer = 0 To 4 '495
                    If pageCheck(i) Then
                        f_page(0) = HIBYTE(i)
                        f_page(1) = LOBYTE(i)
resendPage:
                        If BikiRom_sendCmdd(f_page, f_read, 2, 1) = FT_OK Then
                            Console.WriteLine(Hex(i) & "Past sending page command")
                            If f_read(0) = 170 Then
                                Console.WriteLine(Hex(i) & "past the check of page command")
                                array_copy(m_data, i * 256, f_pageData, 0, 256)
                                s_crc = 0
                                For d As Integer = 0 To 255
                                    s_crc += CByte(f_pageData(d))
                                Next
                                f_pageData(256) = LOBYTE(s_crc)
                                If BikiRom_sendCmdd(f_pageData, f_read, f_pageLength, 2) = FT_OK Then
                                    If f_read(0) = 223 Then
                                        Console.WriteLine(Hex(i) & " Page Written OK")
                                    ElseIf f_read(0) = 222 Or f_read(0) = 238 Then
                                        ' page fail...
                                        Console.WriteLine(Hex(i) & "Page Failed")
                                        f_error += 1
                                        If f_error >= 100 Then
                                            Return False
                                            bootReset()
                                            Exit Function
                                        End If
                                        GoTo resendPage
                                    Else
                                        GoTo resendPage
                                    End If
                                End If
                            Else
                                Console.WriteLine("Error on return from page # " & f_read(0))
                            End If
                        End If
                    End If
                Next
                f_page(0) = 1
                f_page(1) = 255
                BikiRom_sendCmdd(f_page, f_read, 2, 0)
            Else
                f_return = False
            End If
        Else
            f_return = False
        End If
        bootReset()
        Return f_return
    End Function

    Private Sub bootReset()
        FT_SetRts(m_lngHandle)
        Threading.Thread.Sleep(20)
        FT_SetDtr(m_lngHandle)
        Threading.Thread.Sleep(20)
        FT_ClrDtr(m_lngHandle)
        Threading.Thread.Sleep(20)
    End Sub
    Private Sub bootLoad()
        Threading.Thread.Sleep(20)
        FT_ClrRts(m_lngHandle)
        Threading.Thread.Sleep(20)
        FT_SetDtr(m_lngHandle)
        Threading.Thread.Sleep(20)
        FT_ClrDtr(m_lngHandle)
        Threading.Thread.Sleep(20)
    End Sub
End Class
